home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / game / board / Exchess.lha / EXChess / parse.cpp < prev    next >
C/C++ Source or Header  |  1998-08-12  |  8KB  |  241 lines

  1. /* Parse.cpp  - functions for parsing moves */
  2.  
  3. #include "chess.h"
  4. #include "define.h"
  5. #include "funct.h"
  6. #include "const.h"
  7. #include <iostream.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10.  
  11. extern int ics;
  12. // Function to parse a move from the human player
  13. // This move is checked then checked to see if it is legal
  14. move parse_move(position p, char mstring[10])
  15. {
  16.   int legal = 0, piece, to_sq = -1, from_sq = -1, promote = QUEEN;
  17.   int from_file = -1, from_row = -1, match_count = 0;
  18.   move play, mplay[4], nomove; nomove.t = 0;
  19.   mplay[0].t = 0; mplay[1].t = 0; mplay[2].t = 0; mplay[3].t = 0;
  20.   position t_pos;
  21.   move_list list;
  22.  
  23.   // generate the legal moves
  24.   legalmoves(&p, &list);
  25.  
  26.   // Examining input move from a human player - checking for
  27.   // errors and the legality of the move....
  28.  
  29.   // First resolve the first character - what piece is it?
  30.   switch(mstring[0]) {
  31.     case 'N': piece = KNIGHT; break;
  32.     case 'B': piece = BISHOP; break;
  33.     case 'R': piece = ROOK; break;
  34.     case 'Q': piece = QUEEN; break;
  35.     case 'K': piece = KING; break;
  36.     case 'P': piece = PAWN; break;
  37.     case 'O': piece = 10; break;        // if it is a castle
  38.     case '0': piece = 10; break;
  39.     case 'o': piece = 10; break;
  40.     default : piece = PAWN;
  41.   }
  42.  
  43.   if (piece != 10) {  // if is not a castle
  44.  
  45.     // Now cycle throught the rest of the characters looking
  46.     // for move squares, capture signals, or promotion signals
  47.     for(int i = 0; i < 10; i++) {
  48.       if(!i && piece != PAWN) i++;
  49.       switch(mstring[i]) {
  50.         case '\0': i = 10; break;
  51.         case 'x':
  52.           if(CHAR_FILE(mstring[i+1]) <= 7 && CHAR_FILE(mstring[i+1]) >= 0
  53.              && CHAR_ROW(mstring[i+2]) <= 7 && CHAR_ROW(mstring[i+2]) >= 0) {
  54.            from_sq = to_sq;
  55.            to_sq = SQR(CHAR_FILE(mstring[i+1]), CHAR_ROW(mstring[i+2]));
  56.            i += 2; break;
  57.           } else { i += 1; break; }
  58.         case '-':
  59.           if(CHAR_FILE(mstring[i+1]) <= 7 && CHAR_FILE(mstring[i+1]) >= 0
  60.              && CHAR_ROW(mstring[i+2]) <= 7 && CHAR_ROW(mstring[i+2]) >= 0) {
  61.            from_sq = to_sq;
  62.            to_sq = SQR(CHAR_FILE(mstring[i+1]), CHAR_ROW(mstring[i+2]));
  63.            i += 2; break;
  64.           } else { i+= 1; break; }
  65.         case '=':
  66.           switch(mstring[i+1]) {
  67.             case 'N': promote = KNIGHT; break;
  68.             case 'B': promote = BISHOP; break;
  69.             case 'R': promote = ROOK; break;
  70.             case 'Q': promote = QUEEN; break;
  71.           }
  72.           i = 10;
  73.           break;
  74.         case '+': i = 10; break;
  75.         default:
  76.           if (to_sq == -1 && CHAR_ROW(mstring[i+1]) <= 7
  77.                && CHAR_ROW(mstring[i+1]) >=0 && CHAR_FILE(mstring[i]) >= 0
  78.                && CHAR_FILE(mstring[i]) <= 7) {
  79.             to_sq = SQR(CHAR_FILE(mstring[i]), CHAR_ROW(mstring[i+1]));
  80.             i += 1;
  81.           } else {
  82.             if (CHAR_ROW(mstring[i+1]) <= 7 && CHAR_ROW(mstring[i+1]) >= 0
  83.                 && CHAR_FILE(mstring[i]) <= 7 && CHAR_FILE(mstring[i]) >= 0) {
  84.               from_sq = to_sq;
  85.               to_sq = SQR(CHAR_FILE(mstring[i]), CHAR_ROW(mstring[i+1]));
  86.               switch (mstring[i+2]) {
  87.                 case 'q': promote = QUEEN; i++; break;
  88.                 case 'n': promote = KNIGHT; i++; break;
  89.                 case 'b': promote = BISHOP; i++; break;
  90.                 case 'r': promote = ROOK; i++; break;
  91.               }
  92.               i += 1;
  93.             } else {
  94.              if(CHAR_FILE(mstring[i]) <= 7 && CHAR_FILE(mstring[i]) >= 0)
  95.               from_file = CHAR_FILE(mstring[i]);
  96.              else
  97.               from_row = CHAR_ROW(mstring[i]);
  98.             }
  99.           }
  100.           break;
  101.       }
  102.     }
  103.     play.b.from = from_sq;  play.b.to = to_sq;
  104.  
  105.   } else {    // if it is a castle
  106.  
  107.     if (!strcmp(mstring, "O-O") || !strcmp(mstring, "0-0")
  108.         || !strcmp(mstring, "o-o") || !strcmp(mstring, "O-O+")
  109.         || !strcmp(mstring, "0-0+") || !strcmp(mstring, "o-o+")) {
  110.       if (p.wtm) { play.b.from = 4; play.b.to = 6; }
  111.       else { play.b.from = 60; play.b.to = 62; }
  112.     } else if (!strcmp(mstring, "O-O-O") || !strcmp(mstring, "0-0-0")
  113.                || !strcmp(mstring, "o-o-o") || !strcmp(mstring, "O-O-O+")
  114.                || !strcmp(mstring, "0-0-0+") || !strcmp(mstring, "o-o-o+")) {
  115.       if (p.wtm) { play.b.from = 4; play.b.to = 2; }
  116.       else { play.b.from = 60; play.b.to = 58; }
  117.     }
  118.   }
  119.  
  120.  
  121.   // Match up the move in the move list
  122.   for (int z = 0; z < list.count; z++)
  123.   {
  124.    if (match_count > 2) break;
  125.    if (list.mv[z].m.b.to == play.b.to &&
  126.         (promote == list.mv[z].m.b.promote || !list.mv[z].m.b.promote))
  127.     {
  128.      if (list.mv[z].m.b.from == play.b.from) {
  129.        mplay[match_count] = list.mv[z].m;
  130.        match_count++;
  131.      } else if (FILE(list.mv[z].m.b.from) == from_file &&
  132.                  p.sq[list.mv[z].m.b.from].type == piece) {
  133.        mplay[match_count] = list.mv[z].m;
  134.        match_count++;
  135.      } else if (RANK(list.mv[z].m.b.from) == from_row &&
  136.                  p.sq[list.mv[z].m.b.from].type == piece) {
  137.        mplay[match_count] = list.mv[z].m;
  138.        match_count++;
  139.      } else if (from_sq == -1 && from_file == -1 && from_row == -1 &&
  140.                  p.sq[list.mv[z].m.b.from].type == piece) {
  141.        mplay[match_count] = list.mv[z].m;
  142.        match_count++;
  143.      }
  144.     }
  145.   }
  146.  
  147.   // check the case where there are two matches but one might
  148.   // lead to check so is illegal... the other is then a valid move
  149.   while (match_count <= 2 && match_count) {
  150.     t_pos = p;
  151.     legal = exec_move(&t_pos, mplay[0], 0);   // tenatively making the move...
  152.     if(match_count == 1) break;
  153.     t_pos = p;
  154.     if(legal && exec_move(&t_pos, mplay[1], 0))
  155.       { legal = 0; break; }
  156.     else if(legal) break;
  157.     t_pos = p;
  158.     legal = exec_move(&t_pos, mplay[1], 0);
  159.     mplay[0] = mplay[1];
  160.     break;
  161.   }
  162.  
  163.   // if it is not legal
  164.   if (!legal || !match_count) {
  165.     return nomove;
  166.   }
  167.  
  168.   return mplay[0];
  169. }
  170.  
  171. /* Function to print a single move */
  172. // to a string in long algebraic format
  173. // This function works by simply adding the appropriate
  174. // characters to the move string;
  175. void print_move(position p, move pmove, char mstring[10])
  176. {
  177.   char dummy[10];             // dummy character string
  178.   int ptype, pfrom, pto, ppiece;
  179.  
  180.   strcpy(mstring, "");
  181.   strcpy(dummy, "");
  182.  
  183.   if(pmove.b.type&CASTLE) {           // if it is a castle
  184.     if(pmove.b.from > pmove.b.to) sprintf((mstring), "O-O-O");
  185.     else sprintf((mstring), "O-O");
  186.   } else {
  187.     ppiece = p.sq[pmove.b.from].type;
  188.     pfrom = pmove.b.from;
  189.     pto = pmove.b.to;
  190.     ptype = pmove.b.type;
  191.  
  192.     if (ppiece > PAWN)
  193.      { sprintf(mstring, "%c", name[ppiece]); }
  194.     switch(ppiece) {
  195.       case PAWN:
  196.         if(ptype&CAPTURE)
  197.          sprintf(dummy,"%c", char(FILE(pfrom)+97));
  198.         break;
  199.       case KING:
  200.         strcpy(dummy, ""); break;
  201.       default:
  202.         move_list list;
  203.         int add_file = 0;
  204.  
  205.         // generate the legal moves
  206.         legalmoves(&p, &list);
  207.         // Match up the move in the move list
  208.         for (int z = 0; z < list.count; z++) {
  209.          if (list.mv[z].m.b.to == pto && list.mv[z].m.b.from != pfrom &&
  210.               ppiece == p.sq[list.mv[z].m.b.from].type) {
  211.            if(!add_file) { 
  212.              sprintf(dummy,"%c", char(FILE(pfrom)+97));
  213.              add_file = 1;
  214.            }
  215.            if(FILE(pfrom) == FILE(list.mv[z].m.b.from)) {
  216.              char dummy2[2];
  217.              sprintf(dummy2,"%i", (RANK(pfrom)+1));
  218.              strcat(dummy,dummy2);
  219.              z = list.count;
  220.            }             
  221.          }        
  222.         }        
  223.     }
  224.     if(ptype&CAPTURE) strcat(dummy,"x");      
  225.     strcat(mstring, dummy);
  226.     sprintf(dummy, "%c%i", char(FILE(pmove.b.to)+97), (RANK(pmove.b.to)+1));
  227.     strcat(mstring, dummy);
  228.     if (pmove.b.type&PROMOTE) {
  229.       strcat(mstring, "="); sprintf(dummy, "%c", name[pmove.b.promote]);
  230.       strcat(mstring, dummy);
  231.     }
  232.   }
  233.  
  234.   // now execute the move and see if it leads to check or check-mate...
  235.   e